﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using Microsoft.Office.Interop.Excel;
using Newtonsoft.Json;
using System.Windows.Forms;
using System.Collections;

namespace ExcelJsonParser
{
    public partial class Toolbar
    {
        Hashtable _dataTypes = new Hashtable();
        //List<string> _dataTypes = new List<string>();
        List<string> importButtonNames = new List<string>();
        private void Toolbar_Load(object sender, RibbonUIEventArgs e)
        {
            InitTypes();
            foreach (string type in _dataTypes.Keys)
            {
                RibbonDropDownItem rItem = this.Factory.CreateRibbonDropDownItem();
                rItem.Label = type;
                dataTypeDisplay.Items.Add(rItem);
            }
            JsonWorkApp.SelectionChanged += new JsonWorkApp.onSelectionChanged(Toolbar_SelectionChanged);
        }

        void InitTypes()
        {
            _dataTypes.Add(JsonValueTypes.String.ToString(), typeof(String));
            _dataTypes.Add(JsonValueTypes.Null.ToString(), null);
            _dataTypes.Add(JsonValueTypes.Undefined.ToString(), JsonWorkCell.jsonUndefined);
            _dataTypes.Add(JsonValueTypes.Bool.ToString(), typeof(Boolean));
            _dataTypes.Add(JsonValueTypes.Int.ToString(), typeof(Int64));
            _dataTypes.Add(JsonValueTypes.Double.ToString(), typeof(Double));
            _dataTypes.Add(JsonValueTypes.JsonObject.ToString(), typeof(JavaScriptObject));
            _dataTypes.Add(JsonValueTypes.JsonArray.ToString(), typeof(JavaScriptArray));
        }

        void Toolbar_SelectionChanged(Range Target)
        {
            object javaObject = null;
            JsonValueTypes jType = JsonWorkCell.GetJsonTypeFromCell(Target, out javaObject);
            if (javaObject is JavaScriptArray || javaObject is JavaScriptObject)
            {
                try
                {
                    valueDisplay.Text = JavaScriptConvert.SerializeObject(javaObject);
                }
                catch (Exception ex)
                {

                    valueDisplay.Text = ex.Message;
                }
                
            }
            else
            {
                if (javaObject != null)
                {
                    valueDisplay.Text = javaObject.ToString();
                }
                
            }
            foreach (RibbonDropDownItem item in dataTypeDisplay.Items)
            {
                if (item.Label.Equals(jType.ToString()))
                {
                    dataTypeDisplay.SelectedItem = item;
                    break;
                }
            }
        }

        private void importJsonStringGallery_Click(object sender, RibbonControlEventArgs e)
        {
            string jsonString = "";
            JsonInputDialog jsdialog = new JsonInputDialog();
            if (jsdialog.ShowDialog() == DialogResult.OK)
            {
                jsonString = jsdialog.JsonInput;
                RibbonGallery importGallery = sender as RibbonGallery;
                string action = importGallery.SelectedItem.Label;
                switch (action)
                {
                    case "Workbook":
                        JsonWorkApp.GetInstance().ImportJsonString(jsonString);
                        break;
                    case "Worksheet":
                        JsonWorkApp.GetInstance().ImportJsonStringIntoCurrentWorkSheet(jsonString);
                        break;
                    default:
                        break;
                }
            }
        }

        private void importJsonFileGallery_Click(object sender, RibbonControlEventArgs e)
        {
            if (openJsonFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (System.IO.File.Exists(openJsonFileDialog.FileName))
                {
                    string jsonString = System.IO.File.ReadAllText(openJsonFileDialog.FileName);
                    RibbonGallery importGallery = sender as RibbonGallery;
                    string action = importGallery.SelectedItem.Label;
                    switch (action)
                    {
                        case "Workbook":
                            JsonWorkApp.GetInstance().ImportJsonString(jsonString);
                            break;
                        case "Worksheet":
                            JsonWorkApp.GetInstance().ImportJsonStringIntoCurrentWorkSheet(jsonString);
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        private void exportJson_Click(object sender, RibbonControlEventArgs e)
        {
            if (saveJsonFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                
                RibbonGallery importGallery = sender as RibbonGallery;
                string action = importGallery.SelectedItem.Label;
                string jsonString = "";
                switch (action)
                {
                    case "Workbook":
                        jsonString = JsonWorkApp.GetInstance().ExportCurrentWorkBook();
                        break;
                    case "Worksheet":
                        jsonString = JsonWorkApp.GetInstance().ExportCurrentWorkSheet();
                        break;
                    default:
                        break;
                }
                System.IO.File.WriteAllText(saveJsonFileDialog.FileName, jsonString);
            }
        }

        private void displayJson_Click(object sender, RibbonControlEventArgs e)
        {
            string jsonString = "";
            RibbonGallery importGallery = sender as RibbonGallery;
            string action = importGallery.SelectedItem.Label;
            switch (action)
            {
                case "Workbook":
                    jsonString = JsonWorkApp.GetInstance().ExportCurrentWorkBook();
                    break;
                case "Worksheet":
                    jsonString = JsonWorkApp.GetInstance().ExportCurrentWorkSheet();
                    break;
                default:
                    break;
            }
            JsonViewer jv = new JsonViewer(jsonString);
            jv.ShowDialog();
        }

        private void dataTypeDisplay_SelectionChanged(object sender, RibbonControlEventArgs e)
        {
            RibbonDropDown rdd = sender as RibbonDropDown;
            string convert2Type = rdd.SelectedItem.ToString();
            JsonWorkApp.GetInstance().ConvertSelectedCell(_dataTypes[convert2Type]);
        }

        private void abapFormatConvert_Click(object sender, RibbonControlEventArgs e)
        {
            string jsonString = "";
            RibbonGallery importGallery = sender as RibbonGallery;
            
            string ABAPVarName = "";
            string ABAPCode = "";
            ABAPVariantNameInput inputForm = new ABAPVariantNameInput();
            DialogResult dr = inputForm.ShowDialog();
            if (dr == DialogResult.OK)
            {
                string action = importGallery.SelectedItem.Label;
                ABAPVarName = inputForm.ABAPVariantName;
                List<string> ABAPCodes = new List<string>();
                switch (action)
                {
                    case "Workbook":
                        jsonString = JsonWorkApp.GetInstance().ExportCurrentWorkBook();
                        ABAPCodes = GenerateABAPCode(ABAPVarName,jsonString.Replace("'","''"));
                        ABAPCode = BuildABAPCodes(ABAPCodes);
                        break;
                    case "Worksheet":
                        jsonString = JsonWorkApp.GetInstance().ExportCurrentWorkSheet();
                        ABAPCodes = GenerateABAPCode(ABAPVarName, jsonString.Replace("'", "''"));
                        ABAPCode = BuildABAPCodes(ABAPCodes);
                        break;
                    default:
                        break;
                }
                JsonViewer jv = new JsonViewer(ABAPCode);
                jv.ShowDialog();
            }
            if (dr == DialogResult.Yes)
            {
                int maxLenght = 0;
                if (int.TryParse(inputForm.MaxLineLength, out maxLenght))
                {
                    string action = importGallery.SelectedItem.Label;
                    switch (action)
                    {
                        case "Workbook":
                            jsonString = JsonWorkApp.GetInstance().ExportCurrentWorkBook();
                            break;
                        case "Worksheet":
                            jsonString = JsonWorkApp.GetInstance().ExportCurrentWorkSheet();
                            break;
                        default:
                            break;
                    }
                    JsonViewer jv = new JsonViewer(BuildJsonLines(jsonString, maxLenght));
                    jv.ShowDialog();
                }
            }
        }

        string BuildJsonLines(string jsonString, int maxLength)
        {
            string returnJsonLines = "";
            if (jsonString.Length > maxLength)
            {
                string firstSubString = jsonString.Substring(0, maxLength) + Environment.NewLine;
                string lastSubString = jsonString.Substring(maxLength, jsonString.Length - maxLength);
                returnJsonLines = firstSubString + BuildJsonLines(lastSubString,maxLength);
            }
            else
            {
                returnJsonLines = jsonString;
            }
            return returnJsonLines;
        }

        string BuildABAPCodes(List<string> lines)
        {
            string returnABAPCodes = "";
            foreach (string ABAPLine in lines)
            {
                returnABAPCodes = returnABAPCodes + ABAPLine + "\n";
            }
            return returnABAPCodes;
        }

        List<string> GenerateABAPCode(string varName, string varString, Boolean isStart =true)
        {
            List<string> returnABAPCode = new List<string>();
            string line = "";
            string lastLine = "";
            string codeSetValStart = "";
            string codeSetValEnd = "";
            if (isStart)
            {
                codeSetValStart = BeginLine + varName + " = '";
                codeSetValEnd = "'.";    
            }
            else
            {
                //CONCATENATE var '' INTO var.         
                codeSetValStart = BeginLine + "CONCATENATE " + varName + " '";
                codeSetValEnd = "' INTO " + varName + ".";   
            }
            string tempABAPCode = codeSetValStart + varString + codeSetValEnd;
            if (tempABAPCode.Length > MaxLengthInABAPCode)
            {
                int lineLength = MaxLengthInABAPCode - (codeSetValStart.Length + codeSetValEnd.Length);
                line = codeSetValStart + varString.Substring(0, lineLength) + codeSetValEnd;
                returnABAPCode.Add(line);
                lastLine = varString.Substring(lineLength, varString.Length - lineLength);
                returnABAPCode.AddRange(GenerateABAPCode(varName,lastLine, false));
            }
            else
            {
                returnABAPCode.Add(tempABAPCode);
            }
            return returnABAPCode;
        }
        const string BeginLine = "  ";
        const int MaxLengthInABAPCode = 250;
    }
}
